/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Daos;

import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Clases.Usuario;
import Clases.Bus;
import Clases.Ruta;
import Clases.Turno;
import Daos.exceptions.NonexistentEntityException;
import Daos.exceptions.PreexistingEntityException;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author user
 */
public class TurnoJpaController implements Serializable {

    public TurnoJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Turno turno) throws PreexistingEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario codConduc = turno.getCodConduc();
            if (codConduc != null) {
                codConduc = em.getReference(codConduc.getClass(), codConduc.getCodUser());
                turno.setCodConduc(codConduc);
            }
            Bus codbus = turno.getCodbus();
            if (codbus != null) {
                codbus = em.getReference(codbus.getClass(), codbus.getCodBus());
                turno.setCodbus(codbus);
            }
            Ruta codruta = turno.getCodruta();
            if (codruta != null) {
                codruta = em.getReference(codruta.getClass(), codruta.getCodRuta());
                turno.setCodruta(codruta);
            }
            em.persist(turno);
            if (codConduc != null) {
                codConduc.getTurnoList().add(turno);
                codConduc = em.merge(codConduc);
            }
            if (codbus != null) {
                codbus.getTurnoList().add(turno);
                codbus = em.merge(codbus);
            }
            if (codruta != null) {
                codruta.getTurnoList().add(turno);
                codruta = em.merge(codruta);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findTurno(turno.getCodTurno()) != null) {
                throw new PreexistingEntityException("Turno " + turno + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Turno turno) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Turno persistentTurno = em.find(Turno.class, turno.getCodTurno());
            Usuario codConducOld = persistentTurno.getCodConduc();
            Usuario codConducNew = turno.getCodConduc();
            Bus codbusOld = persistentTurno.getCodbus();
            Bus codbusNew = turno.getCodbus();
            Ruta codrutaOld = persistentTurno.getCodruta();
            Ruta codrutaNew = turno.getCodruta();
            if (codConducNew != null) {
                codConducNew = em.getReference(codConducNew.getClass(), codConducNew.getCodUser());
                turno.setCodConduc(codConducNew);
            }
            if (codbusNew != null) {
                codbusNew = em.getReference(codbusNew.getClass(), codbusNew.getCodBus());
                turno.setCodbus(codbusNew);
            }
            if (codrutaNew != null) {
                codrutaNew = em.getReference(codrutaNew.getClass(), codrutaNew.getCodRuta());
                turno.setCodruta(codrutaNew);
            }
            turno = em.merge(turno);
            if (codConducOld != null && !codConducOld.equals(codConducNew)) {
                codConducOld.getTurnoList().remove(turno);
                codConducOld = em.merge(codConducOld);
            }
            if (codConducNew != null && !codConducNew.equals(codConducOld)) {
                codConducNew.getTurnoList().add(turno);
                codConducNew = em.merge(codConducNew);
            }
            if (codbusOld != null && !codbusOld.equals(codbusNew)) {
                codbusOld.getTurnoList().remove(turno);
                codbusOld = em.merge(codbusOld);
            }
            if (codbusNew != null && !codbusNew.equals(codbusOld)) {
                codbusNew.getTurnoList().add(turno);
                codbusNew = em.merge(codbusNew);
            }
            if (codrutaOld != null && !codrutaOld.equals(codrutaNew)) {
                codrutaOld.getTurnoList().remove(turno);
                codrutaOld = em.merge(codrutaOld);
            }
            if (codrutaNew != null && !codrutaNew.equals(codrutaOld)) {
                codrutaNew.getTurnoList().add(turno);
                codrutaNew = em.merge(codrutaNew);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = turno.getCodTurno();
                if (findTurno(id) == null) {
                    throw new NonexistentEntityException("The turno with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Turno turno;
            try {
                turno = em.getReference(Turno.class, id);
                turno.getCodTurno();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The turno with id " + id + " no longer exists.", enfe);
            }
            Usuario codConduc = turno.getCodConduc();
            if (codConduc != null) {
                codConduc.getTurnoList().remove(turno);
                codConduc = em.merge(codConduc);
            }
            Bus codbus = turno.getCodbus();
            if (codbus != null) {
                codbus.getTurnoList().remove(turno);
                codbus = em.merge(codbus);
            }
            Ruta codruta = turno.getCodruta();
            if (codruta != null) {
                codruta.getTurnoList().remove(turno);
                codruta = em.merge(codruta);
            }
            em.remove(turno);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Turno> findTurnoEntities() {
        return findTurnoEntities(true, -1, -1);
    }

    public List<Turno> findTurnoEntities(int maxResults, int firstResult) {
        return findTurnoEntities(false, maxResults, firstResult);
    }

    private List<Turno> findTurnoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Turno.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Turno findTurno(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Turno.class, id);
        } finally {
            em.close();
        }
    }

    public int getTurnoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Turno> rt = cq.from(Turno.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
